<template>
  <div class="plan-list">
    <el-card class="plan-card">
      <template #header>
        <div class="card-header">
          <span>健身计划列表</span>
          <div class="header-actions">
            <el-input
              v-model="searchForm.keyword"
              placeholder="请输入计划名称"
              style="width: 300px; margin-right: 10px"
              clearable
              :maxlength="200"
              @clear="handleSearch"
              @keydown.enter="handleSearch"
            >
              <template #append>
                <el-button icon="Search" @click="handleSearch" :loading="loading" />
              </template>
            </el-input>
            <el-button type="primary" @click="handleAdd">添加计划</el-button>
          </div>
        </div>
      </template>

      <el-table
        :data="planList"
        v-loading="loading"
        style="width: 100%"
        row-key="id"
      >
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="name" label="计划名称" show-overflow-tooltip />
        <el-table-column prop="goal" label="训练目标" width="150" show-overflow-tooltip />
        <el-table-column prop="duration" label="周期(周)" width="100" />
        <el-table-column prop="difficulty" label="难度" width="100">
          <template #default="scope">
            <el-tag :type="getDifficultyTagType(scope.row.difficulty)">
              {{ formatDifficulty(scope.row.difficulty) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="calories" label="卡路里" width="100" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
              {{ scope.row.status === 1 ? '正常' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="创建时间" width="180" />
        <el-table-column label="操作" width="250" fixed="right">
          <template #default="scope">
            <el-button size="small" @click="handleView(scope.row)">查看</el-button>
            <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button
              size="small"
              type="primary"
              @click="handleAssign(scope.row)"
            >
              分配
            </el-button>
            <el-button
              size="small"
              type="danger"
              @click="handleDelete(scope.row)"
              :disabled="scope.row.status === 0"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 添加/编辑计划对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      @close="handleDialogClose"
    >
      <el-form
        ref="planFormRef"
        :model="planForm"
        :rules="planRules"
        label-width="100px"
      >
        <el-form-item label="计划名称" prop="name">
          <el-input v-model="planForm.name" :maxlength="100" show-word-limit />
        </el-form-item>
        <el-form-item label="训练目标" prop="goal">
          <el-input v-model="planForm.goal" :maxlength="100" show-word-limit />
        </el-form-item>
        <el-form-item label="计划周期" prop="duration">
          <el-input-number
            v-model="planForm.duration"
            :min="1"
            :max="52"
            controls-position="right"
            style="width: 100%"
          /> 周
        </el-form-item>
        <el-form-item label="计划难度" prop="difficulty">
          <el-rate
            v-model="planForm.difficulty"
            :max="3"
            :texts="['初级', '中级', '高级']"
            show-text
          />
        </el-form-item>
        <el-form-item label="预计卡路里" prop="calories">
          <el-input-number
            v-model="planForm.calories"
            :min="0"
            :max="5000"
            controls-position="right"
            style="width: 100%"
          /> 千卡
        </el-form-item>
        <el-form-item label="封面图片" prop="coverImage">
          <el-input v-model="planForm.coverImage" placeholder="请输入图片URL" :maxlength="200" />
        </el-form-item>
        <el-form-item label="计划描述" prop="description">
          <el-input
            v-model="planForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入计划描述"
            :maxlength="500"
            show-word-limit
          />
        </el-form-item>
        <el-form-item v-if="isEdit" label="状态" prop="status">
          <el-switch
            v-model="planForm.status"
            :active-value="1"
            :inactive-value="0"
            active-text="正常"
            inactive-text="禁用"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSave" :loading="saveLoading">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 分配计划对话框 -->
    <el-dialog
      v-model="assignDialogVisible"
      title="分配计划"
      width="500px"
    >
      <el-form
        ref="assignFormRef"
        :model="assignForm"
        :rules="assignRules"
        label-width="100px"
      >
        <el-form-item label="会员" prop="memberId">
          <el-select
            v-model="assignForm.memberId"
            placeholder="请选择会员"
            style="width: 100%"
            filterable
          >
            <el-option
              v-for="member in memberList"
              :key="member.id"
              :label="`${member.name} (${member.phone})`"
              :value="member.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="开始日期" prop="startDate">
          <el-date-picker
            v-model="assignForm.startDate"
            type="date"
            placeholder="请选择开始日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="结束日期" prop="endDate">
          <el-date-picker
            v-model="assignForm.endDate"
            type="date"
            placeholder="请选择结束日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 100%"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="assignDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleAssignSave" :loading="assignLoading">分配</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type {
  Plan,
  CreatePlanRequest,
  UpdatePlanRequest,
  AssignPlanRequest
} from '@/types/api/plan'
import type { Member } from '@/types/api/member'
import { planApi } from '@/api/modules/plan'
import { memberApi } from '@/api/modules/member'
import { preventDuplicateSubmit, formUtils } from '@/utils'

// 表格相关
const loading = ref(false)
const planList = ref<Plan[]>([])
const searchForm = reactive({
  keyword: ''
})

// 分页相关
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0
})

// 对话框相关
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)
const saveLoading = ref(false)
const planFormRef = ref()
const currentPlanId = ref(0)

// 分配计划对话框
const assignDialogVisible = ref(false)
const assignLoading = ref(false)
const assignFormRef = ref()
const memberList = ref<Member[]>([])

// 表单数据
const planForm = reactive({
  name: '',
  goal: '',
  duration: 4,
  difficulty: 1,
  calories: 0,
  coverImage: '',
  description: '',
  status: 1
})

const assignForm = reactive({
  memberId: undefined as number | undefined,
  planId: 0,
  startDate: '',
  endDate: ''
})

// 表单验证规则
const planRules = {
  name: [
    { required: true, message: '请输入计划名称', trigger: 'blur' }
  ],
  duration: [
    { required: true, message: '请输入计划周期', trigger: 'blur' }
  ],
  difficulty: [
    { required: true, message: '请选择计划难度', trigger: 'change' }
  ]
}

const assignRules = {
  memberId: [
    { required: true, message: '请选择会员', trigger: 'change' }
  ],
  startDate: [
    { required: true, message: '请选择开始日期', trigger: 'change' }
  ],
  endDate: [
    { required: true, message: '请选择结束日期', trigger: 'change' }
  ]
}

// 获取难度标签类型
const getDifficultyTagType = (difficulty: number) => {
  switch (difficulty) {
    case 1: return 'success'
    case 2: return 'warning'
    case 3: return 'danger'
    default: return 'info'
  }
}

// 格式化难度显示
const formatDifficulty = (difficulty: number) => {
  switch (difficulty) {
    case 1: return '初级'
    case 2: return '中级'
    case 3: return '高级'
    default: return '未知'
  }
}

// 获取健身计划列表
const getPlanList = async () => {
  loading.value = true
  try {
    const response = await planApi.getPlanList({
      page: pagination.page,
      pageSize: pagination.pageSize,
      keyword: searchForm.keyword
    })
    planList.value = response.data.data.list
    pagination.total = response.data.data.total
  } catch (error) {
    ElMessage.error('获取健身计划列表失败')
  } finally {
    loading.value = false
  }
}

// 获取会员列表
const getMemberList = async () => {
  try {
    const response = await memberApi.getMemberList({
      page: 1,
      pageSize: 1000 // 获取所有会员
    })
    memberList.value = response.data.data.list
  } catch (error) {
    ElMessage.error('获取会员列表失败')
  }
}

// 搜索
const handleSearch = () => {
  pagination.page = 1
  getPlanList()
}

// 重置搜索
const handleResetSearch = () => {
  searchForm.keyword = ''
  pagination.page = 1
  getPlanList()
}

// 分页大小改变
const handleSizeChange = (val: number) => {
  pagination.pageSize = val
  pagination.page = 1
  getPlanList()
}

// 当前页改变
const handleCurrentChange = (val: number) => {
  pagination.page = val
  getPlanList()
}

// 添加计划
const handleAdd = () => {
  dialogTitle.value = '添加健身计划'
  isEdit.value = false
  dialogVisible.value = true
  // 重置表单
  Object.assign(planForm, {
    name: '',
    goal: '',
    duration: 4,
    difficulty: 1,
    calories: 0,
    coverImage: '',
    description: '',
    status: 1
  })
}

// 编辑计划
const handleEdit = (row: Plan) => {
  dialogTitle.value = '编辑健身计划'
  isEdit.value = true
  dialogVisible.value = true
  currentPlanId.value = row.id
  // 填充表单数据
  Object.assign(planForm, {
    name: row.name,
    goal: row.goal,
    duration: row.duration,
    difficulty: row.difficulty,
    calories: row.calories,
    coverImage: row.coverImage,
    description: row.description,
    status: row.status
  })
}

// 查看计划详情
const handleView = (row: Plan) => {
  dialogTitle.value = '健身计划详情'
  isEdit.value = false
  dialogVisible.value = true
  currentPlanId.value = row.id
  // 填充表单数据
  Object.assign(planForm, {
    name: row.name,
    goal: row.goal,
    duration: row.duration,
    difficulty: row.difficulty,
    calories: row.calories,
    coverImage: row.coverImage,
    description: row.description,
    status: row.status
  })
}

// 分配计划
const handleAssign = (row: Plan) => {
  assignDialogVisible.value = true
  assignForm.planId = row.id
  // 重置分配表单
  Object.assign(assignForm, {
    memberId: undefined,
    planId: row.id,
    startDate: '',
    endDate: ''
  })
  // 获取会员列表
  getMemberList()
}

// 删除计划
const handleDelete = (row: Plan) => {
  formUtils.handleDeleteConfirm(`健身计划 "${row.name}"`, async () => {
    await planApi.deletePlan(row.id)
    getPlanList()
  }, {
    successMessage: '删除成功',
    errorMessage: '删除失败'
  })
}

// 保存计划信息
const handleSave = async () => {
  if (!planFormRef.value) return

  await planFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      // 使用防重复提交保护
      const submitKey = isEdit.value ? `update_plan_${currentPlanId.value}` : 'create_plan'

      try {
        await preventDuplicateSubmit(submitKey, async () => {
          saveLoading.value = true
          try {
            if (isEdit.value) {
              // 编辑计划
              const updateData: UpdatePlanRequest = {
                name: planForm.name,
                goal: planForm.goal,
                duration: planForm.duration,
                difficulty: planForm.difficulty,
                calories: planForm.calories,
                coverImage: planForm.coverImage,
                description: planForm.description,
                status: planForm.status
              }
              await planApi.updatePlan(currentPlanId.value, updateData)
              ElMessage.success('更新成功')
            } else {
              // 添加计划
              const createData: CreatePlanRequest = {
                name: planForm.name,
                goal: planForm.goal,
                duration: planForm.duration,
                difficulty: planForm.difficulty,
                calories: planForm.calories,
                coverImage: planForm.coverImage,
                description: planForm.description
              }
              await planApi.createPlan(createData)
              ElMessage.success('添加成功')
            }
            dialogVisible.value = false
            getPlanList()
          } catch (error: any) {
            ElMessage.error(isEdit.value ? '更新失败' : '添加失败')
            throw error // 重新抛出错误以确保防重复提交正确处理
          } finally {
            saveLoading.value = false
          }
        })
      } catch (error: any) {
        // 防重复提交保护捕获的错误
        if (error.message === '请勿重复提交') {
          ElMessage.warning('请勿重复提交')
        }
      }
    }
  })
}

// 保存分配信息
const handleAssignSave = async () => {
  if (!assignFormRef.value) return

  await assignFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      assignLoading.value = true
      try {
        const assignData: AssignPlanRequest = {
          memberId: assignForm.memberId!,
          planId: assignForm.planId,
          startDate: assignForm.startDate,
          endDate: assignForm.endDate
        }
        await planApi.assignPlanToMember(assignData)
        ElMessage.success('分配成功')
        assignDialogVisible.value = false
      } catch (error) {
        ElMessage.error('分配失败')
      } finally {
        assignLoading.value = false
      }
    }
  })
}

// 对话框关闭
const handleDialogClose = () => {
  formUtils.resetForm(planFormRef.value, planForm, {
    name: '',
    goal: '',
    duration: 4,
    difficulty: 1,
    calories: 0,
    coverImage: '',
    description: '',
    status: 1
  })
}

// 初始化
onMounted(() => {
  getPlanList()
})
</script>

<style scoped lang="scss">
.plan-list {
  .plan-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .pagination {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
